#include <stdio.h>
#include "show_bmp.h"

int show_fullbmp(char *bmpname)   //printf
{
	int i;
	int x,y;
	int lcdfd;
	int bmpfd;
	// 定义一个数组用于存放bmp的颜色值
	char bmpbuf[800*480*3];  // char占一个字节    bmpbuf[0] bmpbuf[1] bmpbuf[2]一组
	int lcdbuf[800*480]; // int占4字节
	
	// 定义一个临时变量保存颜色值
	int tempbuf[800*480];
	// 打开lcd的驱动
	lcdfd = open("/dev/fb0",O_RDWR);
	// 出错处理
	if(lcdfd == -1)
	{
		printf("open lcd error!\n");
		return -1;
	}
	// 打开你要显示的bmp图片
	bmpfd = open(bmpname,O_RDONLY);
	if(bmpfd == -1)
	{
		printf("open %s failed!\n",bmpname);
		return -1;
	}
	// 在读之前，先跳过前面54字节
	lseek(bmpfd,54,SEEK_SET);
	// 读取bmp图片的颜色值,从55字节位置开始读取了
	read(bmpfd,bmpbuf,800*480*3);
	
	// 将读取的颜色值3字节---》转换成4字节
	for(i=0; i<800*480; i++)
		lcdbuf[i]=bmpbuf[3*i]|bmpbuf[3*i+1]<<8|bmpbuf[3*i+2]<<16|0x00<<24;

	// 将颠倒的图片翻转过来(x,y)--->(x,479-y)
	for(y=0; y<480; y++)
	    for(x=0; x<800; x++)
			//lcdbuf[(479-y)*800+x] = lcdbuf[y*800+x];
			tempbuf[(479-y)*800+x] = lcdbuf[y*800+x];
			
	
	//将转换之后的颜色值写入到lcd的驱动中
	write(lcdfd,tempbuf,800*480*4);
	
	// 关闭lcd和bmp
	close(bmpfd);
	close(lcdfd);
	return 0;
}

// 自定义函数，任意位置显示任意大小的bmp
int show_shapebmp(int x,int y,int w,int h,char *bmpname)   //printf
{
	int i,j;
	int lcdfd;
	int bmpfd;
	int *lcdmem;
	// 定义一个数组用于存放bmp的颜色值
	char bmpbuf[w*h*3];  // char占一个字节    bmpbuf[0] bmpbuf[1] bmpbuf[2]一组
	int lcdbuf[w*h]; // int占4字节
	
	// 打开lcd的驱动
	lcdfd = open("/dev/fb0",O_RDWR);
	// 出错处理
	if(lcdfd == -1)
	{
		printf("open lcd error!\n");
		return -1;
	}

	// 将lcd的地址映射到用户空间
	lcdmem = (int *)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);
	if(lcdmem==NULL)
	{
		printf("map lcd error!\n");
		return -1;
	}
	// 打开你要显示的bmp图片
	bmpfd = open(bmpname,O_RDONLY);
	if(bmpfd == -1)
	{
		printf("open %s failed!\n",bmpname);
		return -1;
	}
	// 在读之前，先跳过前面54字节
	lseek(bmpfd,54,SEEK_SET);
	// 读取bmp图片的颜色值,从55字节位置开始读取了
	read(bmpfd,bmpbuf,w*h*3);
	
	// 将读取的颜色值3字节---》转换成4字节
	for(i=0; i<w*h; i++)
		lcdbuf[i]=bmpbuf[3*i]|bmpbuf[3*i+1]<<8|bmpbuf[3*i+2]<<16|0x00<<24;

	// 将（i,j）---》存放在屏幕（i+x,j+y）的位置
	for(j=0; j<h; j++)
	    for(i=0; i<w; i++)
			*(lcdmem+(j+y)*800+i+x) = lcdbuf[(h-1-j)*w+i];
	// 关闭lcd和bmp
	close(bmpfd);
	close(lcdfd);
	// 解除内存映射
	munmap(lcdmem,800*480*4);
	return 0;
}




int ui_clean_area(int x,int y, int w, int h,int color)
{
	int i,j;
	int lcdfd;
	int bmpfd;
	int *lcdmem;
	// 定义一个数组用于存放bmp的颜色值
	char bmpbuf[w*h*3];  // char占一个字节    bmpbuf[0] bmpbuf[1] bmpbuf[2]一组
	int lcdbuf[w*h]; // int占4字节
	
	// 打开lcd的驱动
	lcdfd = open("/dev/fb0",O_RDWR);
	// 出错处理
	if(lcdfd == -1)
	{
		printf("open lcd error!\n");
		return -1;
	}

	// 将lcd的地址映射到用户空间
	lcdmem = (int *)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);
	if(lcdmem==NULL)
	{
		printf("map lcd error!\n");
		return -1;
	}
	// 将（i,j）---》存放在屏幕（i+x,j+y）的位置
	for(j=0; j<h; j++)
	    for(i=0; i<w; i++)
			*(lcdmem+(j+y)*800+i+x) = color;
	// 关闭lcd和bmp
	close(bmpfd);
	close(lcdfd);
	// 解除内存映射
	munmap(lcdmem,800*480*4);
	return 0;
}



/*将任意大小的图片缩小成某种比例
	参数介绍：x ，y --》左上角x,y坐标
	          w ---》图片的实际宽
			  h ---》图片的实际高
			  scale---》缩小的倍数
			  bmpname---》图片的路径
	代码重点提示：m相当于是缩小之后的图片的宽，n相当于是缩小之后的图片的高
*/           
int show_shortbmp(int x,int y,int w,int h,int scale,char *bmpname)   //printf
{
	int i,j;
	int m,n;
	int lcdfd;
	int bmpfd;
	int *lcdmem;
	// 定义一个数组用于存放bmp的颜色值
	char bmpbuf[w*h*3];  // char占一个字节    bmpbuf[0] bmpbuf[1] bmpbuf[2]一组
	int lcdbuf[w*h]; // int占4字节
	
	// 打开lcd的驱动
	lcdfd = open("/dev/fb0",O_RDWR);
	// 出错处理
	if(lcdfd == -1)
	{
		printf("open lcd error!\n");
		return -1;
	}

	// 将lcd的地址映射到用户空间
	lcdmem = (int *)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcdfd,0);
	if(lcdmem==NULL)
	{
		printf("map lcd error!\n");
		return -1;
	}
	// 打开你要显示的bmp图片
	bmpfd = open(bmpname,O_RDONLY);
	if(bmpfd == -1)
	{
		printf("open %s failed!\n",bmpname);
		return -1;
	}
	// 在读之前，先跳过前面54字节
	lseek(bmpfd,54,SEEK_SET);
	// 读取bmp图片的颜色值,从55字节位置开始读取了
	read(bmpfd,bmpbuf,w*h*3);
	
	// 将读取的颜色值3字节---》转换成4字节
	for(i=0; i<w*h; i++)
		lcdbuf[i]=bmpbuf[3*i]|bmpbuf[3*i+1]<<8|bmpbuf[3*i+2]<<16|0x00<<24;

	// 将（i,j）---》存放在屏幕（i+x,j+y）的位置
	for(j=0,n=0; j<h; j+=scale,n++)
	    for(i=0,m=0; i<w; i+=scale,m++)
			*(lcdmem+(n+y)*800+m+x) = lcdbuf[(h-1-j)*w+i];//将w*h图片上的某个点填充到指定位置
	// 关闭lcd和bmp
	close(bmpfd);
	close(lcdfd);
	// 解除内存映射
	munmap(lcdmem,800*480*4);
	return 0;
}
// 自定义任意位置显示任意大小的bmp
int show_anybmp(int x,int y,int w,int h,char *bmpname)
{
	int bmpfd; //通俗易懂，不要使用拼音
	int lcdfd;
	int i,j;
	//定义数组存放bmp的颜色值
	char bmpbuf[w*h*3];
	int lcdbuf[w*h];
	int tempbuf[w*h];
	//打开你要显示的bmp图片 w*h
	bmpfd=open(bmpname,O_RDWR);//打开开发板中根目录下面的1.bmp
	if(bmpfd==-1) //代码严谨
	{
		printf("open %s failed!\n",bmpname);
		return -1;
	}
	//打开lcd
	lcdfd=open("/dev/fb0",O_RDWR);
	if(lcdfd==-1)
	{
		printf("open lcd failed!\n");
		return -1;
	}
	//跳过图片前面54字节的头信息
	lseek(bmpfd,54,SEEK_SET);
	//读出图片的颜色值
	read(bmpfd,bmpbuf,w*h*3);
	//需要将3字节的数据---》4字节
	for(i=0; i<w*h; i++)
		lcdbuf[i]=bmpbuf[3*i]|bmpbuf[3*i+1]<<8|bmpbuf[3*i+2]<<16|0x00<<24;//拼凑
	                       // 00[2][1][0]
	//将颠倒的图片翻转
	for(j=0; j<h; j++)
	    for(i=0; i<w; i++)
			tempbuf[(h-1-j)*w+i]=lcdbuf[j*w+i];
	//将转换后的颜色值写入到lcd
	/*图片第一行像素点对应tempbuf数组的下标：0---》w-1
	                                        w---》2*w-1
											2*w---》3*w-1
	 如何将液晶屏的光标挪动到(x,y)
	                                   lseek(lcdfd,y*800+x,SEEK_SET);*/
	for(i=0; i<h; i++)
	{
		lseek(lcdfd,4*((y+i)*800+x),SEEK_SET);//起始位置
		write(lcdfd,&tempbuf[w*i],w*4);
	}
	//关闭
	close(bmpfd);
	close(lcdfd);
	return 0;
}

#if 0
int main(int argc, char *argv[])
{
    
    return 0;
}
#endif
